package com.lt.flashcard.view;

import java.util.List;

import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.Clients;

import com.lt.flashcard.Utility;
import com.lt.flashcard.model.entity.Journey;
import com.lt.flashcard.model.entity.JourneyHistory;
import com.lt.flashcard.model.entity.User;
import com.lt.flashcard.model.service.AAService;
import com.lt.flashcard.model.service.LearningService;
import com.lt.flashcard.model.service.Repository;
import com.lt.flashcard.model.service.UserService;

public class ProfileJourneyVm {
	
	private User user;
	private List<Journey> journeys;
	private Journey journey; //Current journey
	private boolean owner = false;
	private int journeyFrom = 0;

	@Init
	public void init() {
		String Id = Executions.getCurrent().getParameter("id");
		AAService asrv = Repository.getInstance().getAAService();
		User cuser = asrv.getCurrentUser();
		if(Id == null) {
			if(!asrv.isLogin()) {
				Utility.loginOrAccessDenied(false);
				return;
			}
			else {
				user = cuser;
			}
		}
		else {
			UserService usrv = Repository.getInstance().getUserService();
			user = usrv.findByID(new Long(Id));
			if(user == null) {
				Utility.displayAccessDenied(false);
				return;
			}
		}
		
		if(user != null && asrv.isAdmin(user)){
			if(cuser == null || (cuser != null && !user.getId().equals(cuser.getId()))){
				Utility.displayAccessDenied(false);
				return;
			}
		}

		//check privacy to access this page
		if(!asrv.checkProfilePrivacy(asrv.getCurrentUser(), user, User.PRIVACYGROUP_JOURNEY)) {
			Utility.displayAccessDenied(false);
			return;
		}
		
		LearningService lsrv = Repository.getInstance().getLearningService();
		loadJourneys();
		journey = lsrv.getCurrentJourney(getUser().getId());
		
		for(journeyFrom = 0; journeyFrom < journeys.size(); journeyFrom ++) {
			JourneyHistory his = journeys.get(journeyFrom).getHistory(user);
			if(his == null || !his.isFinished())
				break;
		}
		
		owner = asrv.getCurrentUser() != null && getUser().getId().equals(asrv.getCurrentUser().getId());
	}
	
	private void loadJourneys() {
		LearningService lsrv = Repository.getInstance().getLearningService();
		setJourneys(lsrv.getAllJourneys());
	}
	
	@Command
	public void startjourney(@BindingParam("id") String id) {
		if(journey != null && !journey.getHistory().isFinished()) {
			return;
		}
		
		int i;
		for(i = 0; i < journeys.size(); i++)
			if(journeys.get(i).getId().toString().equals(id))
				break;
		
		if(i != journeyFrom)
			return;
		
		Journey journey = journeys.get(i);
			
		if(!Utility.isEmptyString(id)) {
			LearningService lsrv = Repository.getInstance().getLearningService();
			//TODO check this
			JourneyHistory his = lsrv.getJourneyHistoryOfUser(getUser().getId(), journey);
			if(his == null) {
				his = lsrv.newJourneyHistory(getUser().getId(), journey);
				his.setStatus(JourneyHistory.STATUS_STARTED);
				lsrv.saveJourneyHistory(his);
				
				this.journey = journey;
				
				BindUtils.postNotifyChange(null, null, this, "journey");
				BindUtils.postNotifyChange(null, null, this, "journeys");
			}
			else {
				Clients.evalJavaScript("showNotice('You have to finish current journey')");
			}
		}
	}
	
	@NotifyChange({"journey", "journeys"})
	@Command
	public void getitem(@BindingParam("index") int index) {
		LearningService lsrv = Repository.getInstance().getLearningService();
		lsrv.getJourneyItem(getUser(), journey, index);
		loadJourneys();
	}
	
	/**
	 * Check if user can get this item
	 * @param index
	 * @return
	 */
	public int checkAvailable(int index) {
		LearningService lsrv = Repository.getInstance().getLearningService();
		return lsrv.checkCanGetItem(getUser(), journey, index);
	}
	
	public boolean isOwner() {
		return this.owner;
	}
	
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public List<Journey> getJourneys() {
		return journeys;
	}

	public void setJourneys(List<Journey> journeys) {
		this.journeys = journeys;
	}

	public Journey getJourney() {
		return journey;
	}

	public void setJourney(Journey journey) {
		this.journey = journey;
	}

	/**
	 * @return the journeyFrom
	 */
	public int getJourneyFrom() {
		return journeyFrom;
	}

	/**
	 * @param journeyFrom the journeyFrom to set
	 */
	public void setJourneyFrom(int journeyFrom) {
		this.journeyFrom = journeyFrom;
	}
}